<?php
/**
 * Created by PhpStorm.
 * User: Administrator
 * Date: 2018-09-19
 * Time: 14:55
 */
namespace app\index\controller;
use PhpOffice\PhpSpreadsheet\Spreadsheet;
use PhpOffice\PhpSpreadsheet\Writer\Xls;
use PhpOffice\PhpSpreadsheet\Style\Color;
use PhpOffice\PhpSpreadsheet\Style;

use think\Debug;
/**
 * 作业单管理
 * Class JobCard
 * @package app\index\controller
 */
class JobCard
{
    //作业单
    const jobcard_maintenance = [
        'majorId'   =>'',     //专业
        'majorName' =>'',     //专业名
        'deviceId'  =>'',     //设备id          -->equiprecord(devicdId)
        'deviceKind'=>'',     //设备名
        'deviceNum' =>'',     //设备数量
        'dateTime'  =>'',     //派单时间
        'state'     =>'开始维保',//状态
        'checkTime'=>'',      //季检/月检  6/3
        'cycle'=>'',          //检修周期
        'taskBillName'=>'',   //作业单名称
    ];
    //作业设备
    const jobcard_devices = [
        'parentId'=>'',           //作业单id
        'floor'=>'',              //楼层
        'deviceNum'=>'',          //设备号
        'receiverId'=>'',         //领取人Id      -->usermange(id)
        'receiverName'=>'',       //领取人名称
        'state'=>'开始维保',       //状态
        'taskDenoteContent'=>[],  //作业指示内容
        'mattersAttention'=>[],   //注意事项
        'versionNumber'=>'',      //版本号
        'changeStatus'=>'',       //修改状态
        'planDateTime'=>'',       ////计划维修日期
        'completeTime'=>'',       //完成时间
        'job'=>'',                //作业
        'workHour'=>'',           //工时
        'fileNumber'=>'',         //文件编号
        'remark'=>'',             //备注信息
    ];

    public static function getData($where, $one = true, $table = 'jobcard_maintenance')
    {
        return ($one == true) ? getFirst(mongo($table)->where($where)->select()) : mongo($table)->where($where)->select();
    }
    public static function setData($where, $data, $table = 'jobcard_maintenance')
    {
        mongo($table)->where($where)->update($data);
    }
    public static function insertData($data, $table = 'jobcard_maintenance')
    {
        mongo($table)->insert($data);
        return mongo($table)->getLastInsID();
    }
    public static function deleteData($where, $table = 'jobcard_maintenance')
    {
        mongo($table)->where($where)->delete();
    }

    /**
     * function 获取所有临近时间维保作业单， 分页处理
     * @access
     * @param string $majorId       设备专业id == null获取本人所有可以维保的作业单
     * @param string $dateTime      作业单临近时间
     * @param string $currentPage   当前页
     * @param string $pageSize      每页大小
     * @return array
     */
    public static function getAllTaskBillExpired($majorId = null, $dateTime = null, $currentPage = null, $pageSize = null)
    {
        if(!empty($perssion = perssion([LOGIN, SHOP]))) { return RD(NO_LOGIN);}  //权限判断
        // var init
        $majorId     = input('majorId');
        $dateTime    = input('dateTime');
        $currentPage = input('currentPage');
        $pageSize    = input("pageSize");

        self::autoNewSendOrders();  //到期自动派单

        $where = [
            'dateTime' => ['like', $dateTime],
        ];

        if(!empty($majorId)) {
            $where['majorId'] = $majorId;
            $alljobcard = self::getData($where, false, 'jobcard_maintenance');
            $count = count($alljobcard);
            array_paging($alljobcard, ($currentPage - 1)* $pageSize, $pageSize);
        } else {  //获取自己所属专业
            $positionId = User::getData(['id'=>cookie('userId')])['position_id'] ?? '';
            $where['majorId'] = $positionId;
            $alljobcard = self::getData($where, false, 'jobcard_maintenance');
            $count = count($alljobcard);
            array_paging($alljobcard, ($currentPage - 1)* $pageSize, $pageSize);
        }
        return RD(SUCCESS, ['total'=>$count, 'currentPage'=>$currentPage, 'orders'=>$alljobcard]); //返回数据
    }
    /**
     * 自动派单 新的
     * @param array
     */
    public static function autoNewSendOrders()
    {
        $currentTime = sprintf("%s--%s", date('n'), ceil(date('j')/7) > 4 ? 4 : ceil(date('j')/7));

        $allMajor = EquipRecord::getData(['parentId'=>User::getStoreId()], false);

        foreach ($allMajor as $major) {
            $majorId = $major['id'] ?? '';
            //获取所有设备检修周期
            $allCycle =  Maintenance::getDeviceCycleDb($majorId)['data'];

            foreach ($allCycle as $value) {
                foreach ($value['cycle'] as $cycle) {

                    if(strstr($cycle, $currentTime)) {
                        $checkTime = explode("--", $cycle)[2] ?? '';
                        if(empty($checkTime))
                            continue;

                        $deviceId  = $value['deviceId'];
                        //到期自动派单//是否添加作业单
                        $where = ['deviceId'=>$deviceId, 'cycle'=>$cycle, 'dateTime'=>['>', date('Y')]];  //本年

                        $alljobcard = self::getData($where);  //获取作业单

                        if(empty($alljobcard)) { //自动派单

                            $insertData = [
                                'majorId'      =>$majorId,
                                'majorName'    =>EquipRecord::getData(['id'=>$majorId])['name'] ?? '',
                                'deviceId'     =>$deviceId,
                                'deviceKind'   =>EquipRecord::getData(['id'=>$deviceId])['name'] ?? '',
                                'deviceNum'    =>EquipRecord::getData(['id'=>$deviceId])['number'] ?? '',
                                'dateTime'     =>date('Y-m-d'),
                                'state'        =>'开始维保',
                                'checkTime'    =>$checkTime,
                                'cycle'        =>$cycle,
                                'taskBillName' =>$major['name'],
                            ];
                            $jobCardId = self::insertData(array_merge(self::jobcard_maintenance, $insertData));       //插入维保作业单数据
                            //添加具体作业设备
                            $tempData = self::jobcard_devices;
                            $tempData['parentId'] = $jobCardId;                             //作业指示
                            $devices = [];
                            EquipRecord::getDevicesByType($deviceId, '子设备', $devices);
                            foreach ($devices as $device) {
                                $tempData['floor']     = EquipRecord::getData(['id'=>$device['id']])['floor'] ?? '';       //楼层
                                $tempData['deviceNum'] = $device['name'];   //设备编号
                                self::insertData($tempData);       //插入维保作业单数据
                            }
                            //添加新消息
                            $users  = User::getData(['position_id'=>$major['id']], false);
                            foreach ($users as $people) {
                                Message::insertData(['userId'=>$people['id'], 'messageType'=>'作业单', 'state'=>'未查看']);
                            }
                        }
                    }
                }
            }
        }
    }
    /**
     * function                         获取作业单下所有设备列表
     * @access
     * @param string $id                作业单id
     * @param string $floorValue        楼层  1F
     * @param string $keyword           关键字  维保作业书名称、设备编号
     * @param int $currentPage          当前页
     * @param string $pageSize          每页大小
     * @return array
     */
    public static function getTaskBillInfoList($id = null, $floorValue = null, $keyword = null, $currentPage = null, $pageSize = null)
    {
        if(!empty($perssion = perssion([LOGIN, SHOP]))) { return RD(NO_LOGIN);}  //权限判断
        if(empty($vars = getInputAll('id', 'floorValue', 'keyword', 'currentPage', 'pageSize'))) {
            return RD(PARA_NOT_NULL);
        }
        //var init
        $id          = input('id');
        $floorValue  = input('floorValue');
        $keyword     = input('keyword');
        $currentPage = input('currentPage/d');
        $pageSize    = input('pageSize');

        $data = [];
        $jobCard = self::getData(['id'=>$id]);
        $jobcard_devices = self::getData(['parentId'=>$id, 'floor'=>['like', '.*'.$floorValue.'.*',], 'deviceNum'=>['like', '.*'.$keyword.'.*']]);//获取作业单数据
        foreach ($jobcard_devices as $key=>$device) {
            $device['deviceKind']       = $jobCard['deviceKind'];
            $device['taskBillName']     = $jobCard['taskBillName'];
            $device['checkTime']        = $jobCard['checkTime'];
            $device['instructions']     = EquipRecord::getData(['id'=>$jobCard['deviceId']])['instructions']??[];
            array_push($data, $device);
        }
        $count = count($data);
        array_paging($data, ($currentPage - 1)* $pageSize, $pageSize);
        return RD(SUCCESS, ['total'=>$count, 'orders'=>$data]);
    }
    /**
     * function        编辑维保设备作业详细内容
     * @access
     * @param string $id                    //维保设备作业id
     * @param string $receiverId            //作业人id
     * @param array  $taskDenoteContent     //作业内容
     * @param string $job                   //作业
     * @param string $workHour              //工作时长
     * @param string $state                 //状态
     * @param string $planDateTime          //计划时间
     * @param string $completeTime          //完成时间
     * @param string $versionNumber         //版本号
     * @param string $fileNumber            //文件号
     * @param string $changeStatus          //改变状态
     * @param string $remark                //备注信息
     * @param array  $mattersAttention      //注意事项
     * @return array
     */
    public static function editMaintenanceDeviceJob($id = null, $receiverId = null, $taskDenoteContent = null, $job =null, $workHour = null, $state = null, $planDateTime = null,
    $completeTime = null, $versionNumber = null, $fileNumber = null, $changeStatus = null, $remark = null, $mattersAttention = [])
    {
        if(!empty($perssion = perssion([LOGIN, SHOP]))) { return RD(NO_LOGIN);}  //权限判断
        //var
        $id                  = input('id');
        $receiverId          = cookie('userId');
        $taskDenoteContent   = input('taskDenoteContent/a', []);
        $job                 = input('job');
        $workHour            = input('workHour');
        $planDateTime        = input('planDateTime');
        $versionNumber       = input('versionNumber');
        $fileNumber          = input('fileNumber');
        $changeStatus        = input('changeStatus');
        $remark              = input('remark');
        $state               = '完成';
        $mattersAttention    = input('mattersAttention/a', []);

        if(empty($id) || empty($receiverId))  return RD(PARA_NOT_NULL);

        $updateData = [
            'receiverId'       =>$receiverId,         //领取人Id      -->usermange(id)
            'receiverName'     =>User::getData(['id'=>$receiverId])['username'] ?? '',       //领取人名称
            'state'            =>$state,       //状态
            'taskDenoteContent'=>$taskDenoteContent,  //作业指示内容
            'versionNumber'    =>$versionNumber,      //版本号
            'changeStatus'     =>$changeStatus,       //修改状态
            'planDateTime'     =>$planDateTime,       ////计划维修日期
            'completeTime'     =>date('Y-h-d'),       //完成时间
            'job'              =>$job,                //作业
            'workHour'         =>$workHour,           //工时
            'fileNumber'       =>$fileNumber,         //文件编号
            'remark'           =>$remark,             //备注信息
            'mattersAttention' =>$mattersAttention,   //注意事项
        ];
        self::setData(['id'=>$id], $updateData);
        return RD(SUCCESS, $updateData);
    }

    /** 多文件导出
     * @param string $id
     * @return array
     */
    public static function multiexportReportJobCard($id = '')
    {
        if(!empty($perssion = perssion([LOGIN, SHOP]))) { return RD(NO_LOGIN);}  //权限判断
        $id = input('id');
        if(empty($id))
            return RD(PARA_NOT_NULL);

        $filanames = [];

        $jobcard_devices = self::getData(['parent'=>$id]);
        foreach ($jobcard_devices as $key=>$device) {
            $filename = self::exportReportJobCard($device['id']);
            array_push($filanames, $filename);
        }

        $zipName = '作业单批量下载.zip';
        $zip = new \ZipArchive;//使用本类，linux需开启zlib，windows需取消php_zip.dll前的注释
        if ($zip->open($zipName, \ZIPARCHIVE::OVERWRITE | \ZIPARCHIVE::CREATE)!==TRUE) {
            return RD(FAIL, '无法打开文件，或者文件创建失败');
        }
        foreach ($filanames as $filaname) {
            if(file_exists($filaname)){
                $zip->addFile($filaname, $filaname);//第二个参数是放在压缩包中的文件名称，如果文件可能会有重复，就需要注意一下
            }
        }
        $zip->close();
        foreach ($filanames as $filaname) {
            @unlink($filename);
        }
        header("Content-Type: application/force-download");
        header("Content-Disposition: attachment; filename=".$zipName);
        readfile($zipName);
        @unlink($zipName);
    }


    /** 导出一个作业指导书
     * @param string $id 维保作业设备id
     * @return array
     */
    public static function oneexportReportJobCard($id = '')
    {
        if(!empty($perssion = perssion([LOGIN, SHOP]))) { return RD(NO_LOGIN);}  //权限判断
        $id = input('id');
        if(empty($id)) {
            return RD(PARA_NOT_NULL);
        }
        $filename = self::exportReportJobCard($id);
        header("Content-Type: application/force-download");
        header("Content-Disposition: attachment; filename=".$filename);
        readfile($filename);
        @unlink($filename);
    }
    /** 导出一个作业指导书
     * @param string $id 维保作业设备id
     * @return 文件路径
     */
    public static function exportReportJobCard($id)
    {
        $writeData = self::getData(['id'=>$id]);
        $jobCard = self::getData(['id'=>$writeData['parentId']]);

        $spreadsheet = new Spreadsheet();
        $worksheet = $spreadsheet->getActiveSheet();

        $worksheet->setTitle('作业单');
        $worksheet->getColumnDimension('A')->setWidth(20);
        $worksheet->getColumnDimension('B')->setWidth(20);
        $worksheet->getColumnDimension('C')->setWidth(20);
        $worksheet->getColumnDimension('D')->setWidth(20);
        $worksheet->getColumnDimension('E')->setWidth(20);
        $worksheet->getColumnDimension('F')->setWidth(20);
        $worksheet->getColumnDimension('G')->setWidth(20);
        $worksheet->getColumnDimension('H')->setWidth(20);

        $worksheet->setCellValue('A1', '作业书名称:');
        $worksheet->setCellValue('B1', $jobCard['taskBillName'] ?? '');
        $worksheet->setCellValue('A2', '设备种类:');
        $worksheet->setCellValue('B2', $jobCard['deviceKind'] ?? '');
        $worksheet->setCellValue('C2', '设备位置:');
        $worksheet->setCellValue('D2', $writeData['floor'] ?? '');
        $worksheet->setCellValue('E2', '设备编号:');
        $worksheet->setCellValue('F2', $writeData['deviceNum'] ?? '');
        $worksheet->setCellValue('G2', '作业种类:');
        $worksheet->setCellValue('H2', ($jobCard['checkTime'] ?? '').'M');

        $worksheet->setCellValue('A3', '文件编号:');
        $worksheet->setCellValue('B3', $writeData['fileNumber'] ?? '');
        $worksheet->setCellValue('C3', '版本号:');
        $worksheet->setCellValue('D3', $writeData['versionNumber'] ?? '');
        $worksheet->setCellValue('E3', '修改状态:');
        $worksheet->setCellValue('F3', $writeData['state'] ?? '');
        $worksheet->setCellValue('G3', '维修日期:');
        $worksheet->setCellValue('H3', $writeData['planDateTime'] ?? '');

        $worksheet->mergeCellsByColumnAndRow(1, 4, 8, 4);

        $worksheet->mergeCells('A5:B5');
        $worksheet->mergeCells('C5:D5');
        $worksheet->mergeCells('E5:F5');
        $worksheet->mergeCells('G5:H5');

        $worksheet->getStyle('A5')->getAlignment()->setHorizontal(\PhpOffice\PhpSpreadsheet\Style\Alignment::HORIZONTAL_CENTER_CONTINUOUS);
        $worksheet->getStyle('C5')->getAlignment()->setHorizontal(\PhpOffice\PhpSpreadsheet\Style\Alignment::HORIZONTAL_CENTER_CONTINUOUS);
        $worksheet->getStyle('E5')->getAlignment()->setHorizontal(\PhpOffice\PhpSpreadsheet\Style\Alignment::HORIZONTAL_CENTER_CONTINUOUS);
        $worksheet->getStyle('G5')->getAlignment()->setHorizontal(\PhpOffice\PhpSpreadsheet\Style\Alignment::HORIZONTAL_CENTER_CONTINUOUS);

        $worksheet->setCellValue('A5', '作业指示:');
        $worksheet->setCellValue('C5', '现状:');
        $worksheet->setCellValue('E5', '维修内容:');
        $worksheet->setCellValue('G5', '结果:');

        foreach ($writeData['taskDenoteContent']??[] as $key=>$value) {
            $worksheet->mergeCellsByColumnAndRow(1, 6 + $key, 2, 6 + $key);
            $worksheet->mergeCellsByColumnAndRow(3, 6 + $key, 4, 6 + $key);
            $worksheet->mergeCellsByColumnAndRow(5, 6 + $key, 6, 6 + $key);
            $worksheet->mergeCellsByColumnAndRow(7, 6 + $key, 8, 6 + $key);

            $worksheet->setCellValueByColumnAndRow(1, 6 + $key, $value['task'] ?? '');
            $worksheet->setCellValueByColumnAndRow(3, 6 + $key, $value['status'] ?? '');
            $worksheet->setCellValueByColumnAndRow(5, 6 + $key, $value['content'] ?? '');
            $worksheet->setCellValueByColumnAndRow(7, 6 + $key, $value['result'] ?? '');

            $worksheet->getStyleByColumnAndRow(1, 6 + $key)->getAlignment()->setHorizontal(\PhpOffice\PhpSpreadsheet\Style\Alignment::HORIZONTAL_CENTER_CONTINUOUS);
            $worksheet->getStyleByColumnAndRow(3, 6 + $key)->getAlignment()->setHorizontal(\PhpOffice\PhpSpreadsheet\Style\Alignment::HORIZONTAL_CENTER_CONTINUOUS);
            $worksheet->getStyleByColumnAndRow(5, 6 + $key)->getAlignment()->setHorizontal(\PhpOffice\PhpSpreadsheet\Style\Alignment::HORIZONTAL_CENTER_CONTINUOUS);
            $worksheet->getStyleByColumnAndRow(7, 6 + $key)->getAlignment()->setHorizontal(\PhpOffice\PhpSpreadsheet\Style\Alignment::HORIZONTAL_CENTER_CONTINUOUS);
        }
        $currentIndex = 6 + count($writeData['taskDenoteContent']??[]);

        $worksheet->mergeCellsByColumnAndRow(1, $currentIndex, 8, $currentIndex);
        $worksheet->setCellValueByColumnAndRow(1, $currentIndex, '备注:'.($writeData['remark'] ?? ''));
        $currentIndex++;

        $worksheet->mergeCellsByColumnAndRow(1, $currentIndex, 8, $currentIndex);
        $currentIndex++;

        $worksheet->mergeCellsByColumnAndRow(1, $currentIndex, 8, $currentIndex);
        $worksheet->setCellValueByColumnAndRow(1, $currentIndex, '作业指导书:');
        $currentIndex++;

        $instructions = EquipRecord::getData(['id'=>($jobCard['deviceId'] ?? '')])['instructions']??[];
        //作业指示
        foreach ($instructions as $key=>$value) {
            $worksheet->mergeCellsByColumnAndRow(1, $currentIndex, 8, $currentIndex);
            $worksheet->setCellValueByColumnAndRow(1, $currentIndex, ($key + 1).':'.$value['fileName'] ?? '');
            $worksheet->getCellByColumnAndRow(1, $currentIndex)->getHyperlink()->setUrl($value['path']);
            $currentIndex++;
        }
        $currentIndex++;
        $worksheet->mergeCellsByColumnAndRow(1, $currentIndex, 8, $currentIndex);
        $worksheet->setCellValueByColumnAndRow(1, $currentIndex, '注意事项:');
        $currentIndex++;
        foreach ($writeData['mattersAttention'] ?? [] as $key=>$value) {

            $worksheet->mergeCellsByColumnAndRow(1, $currentIndex, 8, $currentIndex);
            $worksheet->setCellValueByColumnAndRow(1, $currentIndex, ($key + 1).':'.$value['content'] ?? '');
            $currentIndex++;
        }
        $worksheet->mergeCellsByColumnAndRow(1, $currentIndex, 8, $currentIndex);
        $worksheet->setCellValueByColumnAndRow(1, $currentIndex, '此表流程：签发、作业、检查、存档（签发、检查为专业主管）');
        $currentIndex++;
        $currentIndex++;

        $worksheet->mergeCellsByColumnAndRow(1, $currentIndex, 2, $currentIndex);
        $worksheet->mergeCellsByColumnAndRow(3, $currentIndex, 4, $currentIndex);
        $worksheet->mergeCellsByColumnAndRow(5, $currentIndex, 6, $currentIndex);
        $worksheet->mergeCellsByColumnAndRow(7, $currentIndex, 8, $currentIndex);

        $worksheet->setCellValueByColumnAndRow(1, $currentIndex, '作业：'.($writeData['job'] ?? ''));
        $worksheet->setCellValueByColumnAndRow(3, $currentIndex, '日期：'.($writeData['completeTime'] ?? ''));
        $worksheet->setCellValueByColumnAndRow(5, $currentIndex, '工时：'.($writeData['workHour'] ?? ''));
        $currentIndex++;

        $writer = new Xls($spreadsheet);
        $filename = ($jobCard['deviceKind'] ?? '').uuid().'.xls';
        $writer->save($filename);
        return $filename;
    }
}
